/*
 * Created on 2007-10-31
 *
 * TODO
 */
package jacky.lanlan.song.extension.spring.aop;

import jacky.lanlan.song.util.Logger;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.Ordered;

/**
 * 评估方法执行性能的拦截器。默认<b>Order : 10</b>
 * <p>
 * 该拦截器使用Log4j输出评估结果。评估后，把评估结果发送到指定的Logger， 若没有设置Logger，则使用
 * <code>Logger.getLogger(MethodExecutionMonitor.class)</code> 作为默认输出。
 * 
 * @author Jacky.Song
 */
@Aspect
public class MethodExecutionMonitor implements Ordered {
	private int order = 10;
	private String loggerName;
	private static final Logger DEFAULT_LOGGER=Logger.getLogger();
	
	public int getOrder() {
		return order;
	}

	public void setOrder(int order) {
		this.order = order;
	}
	
	/**
	 * 设置输出评估结果的Log4j Logger。
	 * 
	 * @param loggerName
	 */
	public void setLoggerName(String loggerName) {
		this.loggerName = loggerName;
	}
	
	@Around(
			"@annotation(jacky.lanlan.song.extension.spring.aop.annotation.PerformanceEvaluate) ||" + // 侦测方法声明上的标注
			"@within(jacky.lanlan.song.extension.spring.aop.annotation.PerformanceEvaluate)"// 侦测类声明上的标注
			)
	public Object monitor(ProceedingJoinPoint pjp) throws Throwable {
		long start = System.nanoTime();
		try {
			return pjp.proceed();
		}
		finally {
			long time = System.nanoTime() - start;// 进入finally块后马上就要计时，以保证尽量精确
			
			Logger logger=null;
			if (loggerName == null) {// 默认
				logger=DEFAULT_LOGGER;
			}
			else {
				logger=Logger.getLogger(loggerName);
			}
			logger.debug("方法 [%s] 执行时间: %3.3f ms", pjp.getSignature().toLongString().split(" ")[3],
					(double) (time / (1000 * 1000)));
		}
	}

}
